/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO.MySQL;

import ClassesUnicas.Pessoa;
import DAO.DAOPessoa;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;

/**
 * DAOPessoaMySQL
 *
 * Versao 1.0
 *
 * Data Criação 04/12/2013
 *
 * @author Igor
 */
public class DAOPessoaMySQL extends DAOConexaoMySQL implements DAOPessoa {

    @Override
    public String sqlPesquisaPadrao(String slqInterno, String idFase, String sqlOrderBy) {
        String sqlPadrao = "";
        sqlPadrao = "select\n"
                + "a.ID_PESSOA,\n"
                + "a.NOME,\n"
                + "DATE_FORMAT(a.DATA_NASCIMENTO,'%d/%m/%Y') as DATA_NASCIMENTO,\n"
                + "a.SEXO,\n"
                + "count(c.ID_INSTANCIA_JOGO) as JOGOS_FINALIZADOS,\n"
                + "a.MATRICULA,\n"
                + "a.CPF\n"
                + "from pessoa a\n"
                + "left outer join jogo b\n"
                + "on a.ID_PESSOA = b.ID_PESSOA\n"
                + "left outer join instancia_jogo c\n"
                + "on b.ID_INSTANCIA_JOGO = c.ID_INSTANCIA_JOGO\n"
                + " and c.TEMPO_JOGO > 0 ";
        if (idFase != null) {
            sqlPadrao = sqlPadrao + "and c.ID_FASE = " + idFase + "\n";
        }
        sqlPadrao = sqlPadrao + slqInterno + "\n"
                + "group by a.ID_PESSOA,\n"
                + "a.NOME,\n"
                + "a.MATRICULA";
        return sqlPadrao;
    }

    @Override
    public String gravaPessoa(Pessoa pessoa) throws Exception {
        String vReturn = "";
        CallableStatement cs;
        cs = this.con.getCon().prepareCall("{? = call GRAVA_PESSOA(?,?,?,?,?,?)}");

        cs.registerOutParameter(1, Types.DECIMAL);
        cs.setLong(2, pessoa.getIdPessoa());
        cs.setString(3, pessoa.getNome());
        cs.setString(4, pessoa.getDataNascimento());
        cs.setString(5, pessoa.getSexo());
        cs.setString(6, pessoa.getMatricula());
        cs.setString(7, pessoa.getCpf());
        cs.execute();
        vReturn = cs.getString(1);

        this.con.getStm().executeBatch();

        return vReturn;
    }

    @Override
    public ArrayList<Pessoa> buscaPessoas(String idPessoa, String nome, String idFase, String orderBy) throws Exception {
        ResultSet result = null;
        ArrayList<Pessoa> pessoas = new ArrayList<Pessoa>();
        Pessoa pessoa;
        String clausulaWhere = "";
        String clausulaOrderBy = "";
        int i = 0;

        //Cria clausula where
        if (idPessoa != null) {
            if (clausulaWhere.isEmpty()) {
                clausulaWhere = "where ";
            } else {
                clausulaWhere = clausulaWhere + " and ";
            }
            clausulaWhere = clausulaWhere + " a.ID_PESSOA = " + idPessoa;
        }

        if (nome != null) {
            if (clausulaWhere.isEmpty()) {
                clausulaWhere = "where ";
            } else {
                clausulaWhere = clausulaWhere + " and ";
            }
            clausulaWhere = clausulaWhere + " a.NOME like '%" + nome + "%'";
        }

        //OrderBy
        if (orderBy != null) {
            clausulaOrderBy = "order by " + orderBy;
        }

        result = this.select.executeQuery(sqlPesquisaPadrao(clausulaWhere, idFase, clausulaOrderBy));

        while (result.next()) {
            pessoa = new Pessoa();

            preenchePessoa(pessoa, result);

            pessoas.add(pessoa);
        }

        return pessoas;
    }

    @Override
    public Pessoa buscaPessoa(long idPessoa) throws Exception {
        ResultSet result = null;
        Pessoa pessoa = null;
        int i = 0;

        result = this.select.executeQuery(sqlPesquisaPadrao("where a.ID_PESSOA = " + idPessoa, null, ""));

        while (result.next()) {
            pessoa = new Pessoa();

            preenchePessoa(pessoa, result);
        }

        return pessoa;
    }

    @Override
    public Pessoa buscaPessoa(String nome) throws Exception {
        ResultSet result = null;
        Pessoa pessoa = null;
        int i = 0;

        result = this.select.executeQuery(sqlPesquisaPadrao("where a.NOME = " + nome, null, ""));

        while (result.next()) {
            pessoa = new Pessoa();

            preenchePessoa(pessoa, result);
        }

        return pessoa;
    }

    @Override
    public long buscaPontuacaoMaxUltimoJogo(long idPessoa, long idFase, long idSubFase) throws Exception {
        long pontuacao = 0;
        ResultSet result = null;

        result = this.select.executeQuery("select (sum(ACERTOU_RESPOSTA)*100 )/count(ACERTOU_RESPOSTA) as PERC_ACERTO_MAX from imagem_sub_fase\n"
                + "where ID_INSTANCIA_SUB_FASE = \n"
                + "(select  distinct \n"
                + "d.ID_INSTANCIA_SUB_FASE\n"
                + "from pessoa a\n"
                + "left outer join jogo b\n"
                + "on a.ID_PESSOA = b.ID_PESSOA\n"
                + "left outer join instancia_jogo c\n"
                + "on b.ID_INSTANCIA_JOGO = c.ID_INSTANCIA_JOGO\n"
                + "left outer join instancia_sub_fase d\n"
                + "on b.ID_INSTANCIA_JOGO = d.ID_INSTANCIA_JOGO\n"
                + "where d.TEMPO_SUB_FASE > 0 "
                +" and a.ID_PESSOA = "+idPessoa+"\n"
                +" and c.ID_FASE = "+idFase+" \n"
                +" and d.ID_SUB_FASE = "+idSubFase+"\n"
                + "order by c.DATA_INICIO desc, d.ID_INSTANCIA_SUB_FASE desc limit 1)\n"
                + "group by ID_INSTANCIA_SUB_FASE;");

        while (result.next()) {
            pontuacao = result.getLong("PERC_ACERTO_MAX");
        }

        return pontuacao;
    }

    @Override
    public int buscaQuantidadeSubFasesFinalizads(long idPessoa) throws Exception {
        int pontuacao = 0;
        ResultSet result = null;

        result = this.select.executeQuery("select distinct count(d.ID_INSTANCIA_JOGO) as QuantidadeSubFasesFinalizadas\n"
                + "from pessoa a\n"
                + "left outer join jogo b\n"
                + "on a.ID_PESSOA = b.ID_PESSOA\n"
                + "left outer join instancia_jogo c\n"
                + "on b.ID_INSTANCIA_JOGO = c.ID_INSTANCIA_JOGO\n"
                + "left outer join instancia_sub_fase d\n"
                + "on c.ID_INSTANCIA_JOGO = d.ID_INSTANCIA_JOGO\n"
                + "where d.TEMPO_SUB_FASE > 0\n"
                + "and a.ID_PESSOA = " + idPessoa + "\n"
                + "group by a.ID_PESSOA"
        );

        while (result.next()) {
            pontuacao = result.getInt("QuantidadeSubFasesFinalizadas");
        }

        return pontuacao;
    }

    private void preenchePessoa(Pessoa pessoa, ResultSet result) throws SQLException {
        pessoa.setIdPessoa(result.getLong("ID_PESSOA"));
        pessoa.setNome(result.getString("NOME"));
        pessoa.setDataNascimento(result.getString("DATA_NASCIMENTO"));
        pessoa.setSexo(result.getString("SEXO"));
        pessoa.setQuantidadeJogos(result.getInt("JOGOS_FINALIZADOS"));
        pessoa.setMatricula(result.getString("MATRICULA"));
        pessoa.setCpf(result.getString("CPF"));
    }
}
